﻿using System;
using System.IO;

namespace NumericalSolution {
  class Poisson2DFVIterativeMain {

    static String outfile = "c:/nsworkspace/poisson2d_fv_iterative.txt";
    static double convergenceCriterion = 1e-2;
    static int numberOfControlVolumes = 20;

    public static void Main() {

      Poisson2DFVIterative sim = new Poisson2DFVIterative();
      sim.NumberOfControlVolumes = numberOfControlVolumes;

      sim.Prepare();
      ROResult2D result = null;
      bool isErrorOverCriterion = true;
      double averageErrorRatio = 0.0;
      int iterationCount = 0;

      while (isErrorOverCriterion) {
        double totalError = 0.0;
        int count = 0;

        result = sim.Solve();        
        for (int i = 0; i < numberOfControlVolumes; i++) {
          for (int j = 0; j < numberOfControlVolumes; j++) {
            double x = sim.posx(i);
            double y = sim.posy(j);
            double exact = u(x, y);
            double numerical = result[i, j];
            totalError += Math.Abs(exact - numerical) / exact;
            count++;
          }
        }

        averageErrorRatio = totalError / count;
        if (averageErrorRatio < convergenceCriterion) {
          isErrorOverCriterion = false;
        }
        iterationCount++;
      }

      StreamWriter writer = File.CreateText(outfile);
      for (int i = 0; i < result.RowLength; i++) {
        for (int j = 0; j < result.ColLength; j++) {
          writer.Write(sim.posx(i) + " ");
          writer.Write(sim.posx(j) + " ");
          writer.WriteLine(result[i, j]);
        }
        writer.WriteLine();
      }
      writer.WriteLine("#AVERAGE ERROR RATIO: " + averageErrorRatio);
      writer.WriteLine("#IETRATION: " + iterationCount); 
      writer.Close();
    }

    private static double u(double x, double y) {
      return x * (x - 1) * y * (y - 1);
    }
  }
}